/**   
 * @Title: LocalCacheContainer.java 
 * @Package com.farms.cache 
 * @Description: TODO(用一句话描述该文件做什么) 
 * @author zjhua@hundsun.com   
 * @date 2016年4月25日 下午9:53:03 
 * @version V1.0   
 */
package com.medsoft.dlcache;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.medsoft.base.utils.JsonUtils;
import com.medsoft.dlcache.mq.LocalCacheQueueListener;
import com.medsoft.dlcache.mq.MQProducer;

/**
 * @author zjhua
 *
 */
@Component("localCacheService")
public class LocalCacheServiceImpl implements LocalCacheService, InitializingBean {
	@Autowired
	private LocalCacheContainer localCacheContainer;
 
	@Value("${localcache.isDist}")
	private boolean isDist = true;
	
	//cache2PublishExchPair=cache1,cache2->MetaExch;cache3,cache4->PriceExch;
	@Value("${localcache.cache2PublishExchPairs}")
	private String cache2PublishExchPairs;
	
	private static Map<String,String> cachePublishExchMap = new HashMap<String,String>();

	@Autowired(required = false)
	private MQProducer mQProducer;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.farms.base.cache.LocalCacheService#getCacheEntry(java.lang.String,
	 * java.lang.String)
	 */
	@Override
	public CacheEntry getCacheEntry(String cacheName, String key) {
		return localCacheContainer.getCacheEntry(cacheName, key);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.farms.base.cache.LocalCacheService#saveCacheEntry(java.lang.String,
	 * com.farms.base.cache.CacheEntry)
	 */
	@Override
	public boolean saveCacheEntry(String cacheName, CacheEntry cacheEntry) {
		boolean isSuccess = false;
		if (isDist) {
			//[OP][cacheName][S][@][cacheKey|cacheEntryStr|cacheEntriesStr]
			// MQ发布保存
			isSuccess = mQProducer.sendDataToQueue(cachePublishExchMap.get(cacheName), null,LocalCacheQueueListener.CACHE_OPERATION_REPLACE + cacheName + "@" + JsonUtils.toJson(cacheEntry));
		} else {
			isSuccess = localCacheContainer.saveCacheEntry(cacheName, cacheEntry);
		}
		return isSuccess;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.farms.base.cache.LocalCacheService#removeCacheEntry(java.lang.String,
	 * java.lang.String)
	 */
	@Override
	public boolean removeCacheEntry(String cacheName, String key) {
		boolean isSuccess = false;
		// MQ发布删除
		if (isDist) {
			// MQ发布保存
			isSuccess = mQProducer.sendDataToQueue(cachePublishExchMap.get(cacheName), null, LocalCacheQueueListener.CACHE_OPERATION_REPLACE + cacheName + "@" + key);
		} else {
			isSuccess = localCacheContainer.removeCacheEntry(cacheName, key);
		}
		return isSuccess;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.farms.base.cache.LocalCacheService#getCache(java.lang.String)
	 */
	@Override
	public Map<String, CacheEntry> getCache(String cacheName) {
		return localCacheContainer.getCache(cacheName);
	}

	// 这里业务上唯一有可能的就是某个字典直接整个替换
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.farms.base.cache.LocalCacheService#replaceCache(java.lang.String,
	 * java.util.concurrent.ConcurrentHashMap)
	 */
	@Override
	public boolean replaceCache(String cacheName,
			ConcurrentHashMap<String, CacheEntry> cache) {
		List<CacheEntry> cacheList = new ArrayList<CacheEntry>();
		for (Entry<String, CacheEntry> entry : cache.entrySet()) {
			cacheList.add(entry.getValue());
		}
		boolean isSuccess = false;
		if (isDist) {
			// MQ发布保存
			isSuccess = mQProducer.sendDataToQueue(cachePublishExchMap.get(cacheName), null,LocalCacheQueueListener.CACHE_OPERATION_REPLACE + cacheName + "S@" + JsonUtils.toJson(cacheList));
		} else {
			isSuccess = localCacheContainer.replaceCache(cacheName, cache);
		}
		return isSuccess;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.hundsun.hitop.base.cache.LocalCacheService#replaceCache(java.lang
	 * .String, java.util.List)
	 */
	@Override
	public boolean replaceCache(String cacheName, List<CacheEntry> caches) {
		boolean isSuccess = false;
		ConcurrentHashMap<String, CacheEntry> cacheMap = new ConcurrentHashMap<String, CacheEntry>();
		for (CacheEntry cache : caches) {
			cacheMap.put(cache.getKey(), cache);
		}
		if (isDist) {
			// MQ发布保存
			isSuccess = mQProducer.sendDataToQueue(cachePublishExchMap.get(cacheName), null,LocalCacheQueueListener.CACHE_OPERATION_REPLACE + cacheName + "S@" + JsonUtils.toJson(caches));
		} else {
			isSuccess = localCacheContainer.replaceCache(cacheName, cacheMap);
		}
		return isSuccess;
	}

	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		if(cache2PublishExchPairs == null || cache2PublishExchPairs.trim().equals("")) {
			System.out.println("本地缓存发布队列映射参数[cache2PublishExchPairs]没有设置，请检查server.properties");
			return;
		}
		for (String cache2PublishExchPair : Arrays.asList(StringUtils.removeEnd(this.cache2PublishExchPairs.trim(), ";").split(";"))) {
			String cacheNames = cache2PublishExchPair.split("->")[0];
			String exchangeName = cache2PublishExchPair.split("->")[1];
			for (String cacheName : cacheNames.split(",")) {
				cachePublishExchMap.put(cacheName, exchangeName);
			}
		}
	}
}
